package com.cssy.xxkj.logic.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.byd.acegiext.domain.User;
import com.cssy.xxkj.logic.contants.BillStatusUtil;
import com.cssy.xxkj.logic.contants.BillTypeConstant;
import com.cssy.xxkj.logic.contants.Constants;
import com.cssy.xxkj.logic.dao.LogicProductionGetDAO;
import com.cssy.xxkj.logic.dao.LogicProductionGetItemDAO;
import com.cssy.xxkj.logic.dao.LogicProductionPlanDAO;
import com.cssy.xxkj.logic.dao.LogicProductionReturnDAO;
import com.cssy.xxkj.logic.dao.LogicProductionReturnItemDAO;
import com.cssy.xxkj.logic.dao.LogicWarehousePriceDAO;
import com.cssy.xxkj.logic.entity.LogicProductionGetDO;
import com.cssy.xxkj.logic.entity.LogicProductionGetItemDO;
import com.cssy.xxkj.logic.entity.LogicProductionReturnDO;
import com.cssy.xxkj.logic.entity.LogicProductionReturnItemDO;
import com.cssy.xxkj.logic.entity.LogicWarehouseDetailsDO;
import com.cssy.xxkj.logic.entity.LogicWarehousePriceDO;
import com.cssy.xxkj.logic.service.ILogicProductionReturnService;
import com.cssy.xxkj.logic.service.ILogicWarehouseInventoryService;
import com.cssy.yd.logic.util.MathUtil;
import com.plat.exception.SyBaseException;
import com.plat.helper.SearchCondition;
import com.plat.helper.SearchConditions;
import com.plat.helper.SearchResult;
import com.plat.util.DateUtils;
import com.plat.util.GlobalResLoader;
import com.plat.util.IDCodeTypeUtil;
import com.plat.util.SessionUtil;
import com.yuendong.sy.po.code.SyCode;
import com.yuendong.sy.service.code.impl.SyCodeService;
@Service("logicProductionReturnService")
public class LogicProductionReturnServiceImpl implements ILogicProductionReturnService{
	private static final Logger logger = Logger.getLogger(LogicProductionReturnServiceImpl.class);
	@Resource(name = "logicProductionReturnDAO")
	private LogicProductionReturnDAO logicProductionReturnDAO;
	@Resource(name = "logicProductionReturnItemDAO")
	private LogicProductionReturnItemDAO logicProductionReturnItemDAO;
	
	@Resource(name = "logicProductionGetDAO")
	private LogicProductionGetDAO logicProductionGetDAO;
	
	@Resource(name = "logicProductionGetItemDAO")
	private LogicProductionGetItemDAO logicProductionGetItemDAO;
	
	@Resource(name = "logicWarehouseInventoryService")
	private ILogicWarehouseInventoryService logicWarehouseInventoryService;
	
	@Resource(name = "syCodeService")
	private SyCodeService syCodeService;
	
	@Resource(name = "logicWarehousePriceDAO")
	private LogicWarehousePriceDAO logicWarehousePriceDAO;
	
	@Resource(name = "logicProductionPlanDAO")
	private LogicProductionPlanDAO logicProductionPlanDAO;
	
	@Override
	public SearchResult findListByExample(SearchConditions scs)
			throws SyBaseException {
		SearchResult rs=new SearchResult(scs);
		List<LogicProductionReturnDO>  list= logicProductionReturnDAO.find(scs);
		rs.setRecordCount(logicProductionReturnDAO.count(scs));
		rs.setResults(list);
		return rs;
	}

	@Override
	public Integer delete(String id, User user) throws SyBaseException {
		LogicProductionReturnDO basic = new LogicProductionReturnDO();
		basic.setBizModifyDate(new Date());
		basic.setBizModifyName(user.getName());
		basic.setId(id);
		basic.setRemoved(1l);
		return logicProductionReturnDAO.deleteBizRemoved(id);
	}

	@Override
	public Integer update(LogicProductionReturnDO t, User user) throws SyBaseException {
		t.setBizModifyDate(new Date());
		t.setBizModifyName(user.getName());
		t.setBizVersionMark(t.getBizVersion());
		t.setBizVersion(t.getBizVersion()+1);
		return logicProductionReturnDAO.updateLogicProductionReturnDO(t);
	}

	@Override
	public LogicProductionReturnDO save(LogicProductionReturnDO t, User user)
			throws SyBaseException {
		Date date=new Date();
		t.setBizCreatorName(user.getName());
		t.setBizCreatorDate(date);
		t.setBizVersion(1);
		logicProductionReturnDAO.insertLogicProductionReturnDO(t);
		return t;
	}

	@Override
	public LogicProductionReturnDO findListById(String id) throws SyBaseException {
		return logicProductionReturnDAO.findLogicProductionReturnDOByPrimaryKey(id);
	}

	@Override
	public void returnSave(HttpServletRequest request,
			LogicProductionReturnDO curAP)throws SyBaseException{
		try{
			String json = request.getParameter("addressInfos");
			List<LogicProductionReturnItemDO> axxlist=JSONArray.parseArray(json, LogicProductionReturnItemDO.class);
			boolean ba=true;
			if(curAP.getId()!=null && !"".equals(curAP.getId())){//修改
				if(!curAP.getZd011BillStatus().equals(BillStatusUtil.PRORETURN_STATUS_FIVE)){
					String zd010OtherDate =request.getParameter("zd010OtherDate");
					curAP.setZd010OtherDate(DateUtils.stringToDate(zd010OtherDate));
					int rt=0;
					rt=this.update(curAP, SessionUtil.getUser(request));
					if(0==rt){
						throw new SyBaseException("您修改的行数据发生改变！请重新打开查看");
					}
					logicProductionReturnItemDAO.deleteProById(curAP.getId());
					List<LogicProductionReturnItemDO> list = this.findByIdItem(curAP,true);
					for (LogicProductionReturnItemDO lii : axxlist){
						if(this.validateSubmit(list, lii)){
							throw new SyBaseException("订单物料”"+lii.getZd002MaterialsName()+"“下单总数量大于订单数量，不合法！");
						}
						lii.setId(IDCodeTypeUtil.getId());
						lii.setZd001ReturnId(curAP.getId());
						logicProductionReturnItemDAO.insertLogicProductionReturnItemDO(lii);
					}
				}
				if (curAP.getZd011BillStatus().equals(BillStatusUtil.PRORETURN_STATUS_FIVE)){
					int rt=0;
					rt=this.update(curAP, SessionUtil.getUser(request));
					if(0==rt){
						throw new SyBaseException("您修改的行数据发生改变！请重新打开查看");
					}
					LogicProductionReturnDO loi = logicProductionReturnDAO.findLogicProductionReturnDOByPrimaryKey(curAP.getId());
					for (LogicProductionReturnItemDO lii : axxlist){
						LogicWarehouseDetailsDO lw = new LogicWarehouseDetailsDO();
						lw.setZd001BillCode(loi.getZd001ReturnCode());
						lw.setZd019Batch(Constants.SYS_DEFAULT_BATCH);
						lw.setZd002BillType(BillTypeConstant.PRORETURN);
						lw.setZd005MaterialsId(lii.getZd002MaterialsId());
						lw.setZd005MaterialsCode(lii.getZd002MaterialsCode());
						lw.setZd005MaterialsName(lii.getZd002MaterialsName());
						lw.setZd006MaterialsSpec(lii.getZd003MaterialsSpec());
						lw.setZd007MaterialsModel(lii.getZd004MaterialsModel());
						lw.setZd009BasicUnit(lii.getZd006Unit());
						lw.setZd012Status(lii.getZd008Status());
						lw.setZd004WhPositionId(lii.getZd011WhLocationId());
						lw.setZd004WhPositionCode(lii.getZd012WhLocationCode());
						lw.setZd003WhId(loi.getZd004Whid());
						lw.setZd003WhCode(loi.getZd004WhCode());
						lw.setZd003WhName(loi.getZd004WhName());
						lw.setBizCreatorName(SessionUtil.getUser(request).getName());
						lw.setBizCreatorDate(new Date());
						lw.setZd011BasicQuantity(lii.getZd007Quantity());
						if(lii.getZd009Price()==null||!(lii.getZd009Price().compareTo(new BigDecimal(0.0))==1)){
							SearchConditions scs = new SearchConditions();
							scs.addCondition("zd002WhCode", loi.getZd004WhCode(),SearchCondition.OP_EQUAL);
							scs.addCondition("zd001MaterialsCode", lii.getZd002MaterialsCode(),SearchCondition.OP_EQUAL);
							scs.addCondition("zd001MaterialsId", lii.getZd002MaterialsId(),SearchCondition.OP_EQUAL);
							scs.setRemovedProperty(null);
							List<LogicWarehousePriceDO> lp=logicWarehousePriceDAO.find(scs);
							if(lp.size()>0){
								if(lp.get(0).getZd007SumPrice()!=null&&lp.get(0).getZd007SumPrice().compareTo(new BigDecimal(0.0))==1){
									lw.setZd013Price(lp.get(0).getZd007SumPrice());
								}else{
									throw new SyBaseException("您没有填写单价,并且查不到该天物料的平均价格为0！入库失败！请填写物料价格");
								}
							}else{
									throw new SyBaseException("您没有填写单价,并且查不到该天物料的平均价格！入库失败！请填写物料价格");
							}
						}else{
							lw.setZd013Price(lii.getZd009Price());
						}
						logicWarehouseInventoryService.updateWhAffstockQuantity(lw, SessionUtil.getUser(request),true);
						}
				}
			}else{
					curAP.setZd001ReturnCode(syCodeService.getCode(BillTypeConstant.PRORETURN,BillTypeConstant.PRORETURN,SyCode.DATE_YYMM,5));
					String id = IDCodeTypeUtil.getId();
					curAP.setId(id);
					String zd010OtherDate =request.getParameter("zd010OtherDate");
					curAP.setZd010OtherDate(DateUtils.stringToDate(zd010OtherDate));
					this.save(curAP, SessionUtil.getUser(request));
					for (LogicProductionReturnItemDO lii : axxlist){
						lii.setId(IDCodeTypeUtil.getId());
						lii.setZd001ReturnId(id);
						logicProductionReturnItemDAO.insertLogicProductionReturnItemDO(lii);
					}
			}
			if(curAP.getZd011BillStatus().equals(BillStatusUtil.PRORETURN_STATUS_FIVE)){
				LogicProductionReturnDO rd= this.findListById(curAP.getId());
				LogicProductionGetDO plan = new LogicProductionGetDO();
				plan.setZd001GetCode(rd.getZd002OriCode());
				List<LogicProductionGetDO> planlist=logicProductionGetDAO.findListByExample(plan);
				if(planlist!=null&&!planlist.isEmpty()&&planlist.size()>0){
					if(this.validateReturn(this.findByIdItem(curAP,false), planlist.get(0).getId())){
						planlist.get(0).setZd017ReturnStastus(2l);
					}else{
						planlist.get(0).setZd017ReturnStastus(1l);
					}
					planlist.get(0).setBizVersionMark(planlist.get(0).getBizVersion());
					planlist.get(0).setBizVersion(planlist.get(0).getBizVersion()+1);
					int lp=logicProductionGetDAO.updateLogicProductionGetDO(planlist.get(0));
					if(lp==0){
						throw new SyBaseException("您操作的原始单据数据发生了改变!请您重新打开编辑！");
					}
					logger.info("更新生产领料单仓库状态成功");
				}
			}
			logger.info("生产退料操作成功!");
		}catch(Exception e){
			e.printStackTrace();
			logger.info("生产退料操作失败！");
			throw new SyBaseException(GlobalResLoader.getOpfailed()
					+ e.getMessage());
		}
	}

	@Override
	public Integer deleteBizRemoved(String id) throws SyBaseException {
		return logicProductionReturnDAO.deleteBizRemoved(id);
	}

	@Override
	public List<LogicProductionReturnItemDO> findReturnItemList(String inId)
			throws SyBaseException {
		SearchConditions scs = new SearchConditions();
		scs.setRemovedProperty(null);
		scs.addCondition("zd001ReturnId", inId, SearchCondition.OP_EQUAL);
		List<LogicProductionReturnItemDO>  list=logicProductionReturnItemDAO.find(scs);
		return list;
	}
	
	/**
	 * 验证退料数量是否合法
	 * @param list
	 * @param ItemDO
	 * @return
	 */
	private boolean validateSubmit(List<LogicProductionReturnItemDO> list,LogicProductionReturnItemDO ItemDO){
		BigDecimal bg = MathUtil.mathUtil.subtract(ItemDO.getZd020DdQuanlity(),ItemDO.getZd007Quantity());
		if(list!=null&&!list.isEmpty()&&list.size()>0){
			for(int i=0;i<list.size();i++){
				if(ItemDO.getZd002MaterialsCode().equals(list.get(i).getZd002MaterialsCode())){
					bg=MathUtil.mathUtil.subtract(bg, list.get(i).getZd007Quantity());
				}
			}
		}
		if(bg.compareTo(new BigDecimal(0))==-1){
			return true;
		}
		return false;
	}
	
	private List<LogicProductionReturnItemDO> findByIdItem(LogicProductionReturnDO curAP,boolean bl){
		List<LogicProductionReturnItemDO> list = new ArrayList<LogicProductionReturnItemDO>();
		SearchConditions scs = new SearchConditions();
		scs.setRemovedProperty("removed");
		if(bl){
			scs.addCondition("zd001ReturnCode", curAP.getZd001ReturnCode(), SearchCondition.OP_NOTEQUAL);
		}
		scs.addCondition("zd002OriCode", curAP.getZd002OriCode(), SearchCondition.OP_EQUAL);
		scs.addCondition("zd011BillStatus", Arrays.asList(BillStatusUtil.PRORETURN_STATUS_TWO, BillStatusUtil.PRORETURN_STATUS_THREE, BillStatusUtil.PRORETURN_STATUS_FIVE));
		List<LogicProductionReturnDO> result = this.findListByExample(scs).getResults();
		if(result!=null&&!result.isEmpty()&&result.size()>0){
			for(int i=0;i<result.size();i++){
				List<LogicProductionReturnItemDO> dispatItem = this.findReturnItemList(result.get(i).getId());
				list.addAll(dispatItem);
			}
		}
		return list;
	}
	
	/**
	 * 验证是否已经全部退料完成
	 * @param list
	 * @param planId
	 * @return
	 */
	private boolean validateReturn(List<LogicProductionReturnItemDO> list,String getId){
		LogicProductionGetItemDO getitem = new LogicProductionGetItemDO();
		getitem.setZd001GetId(getId);
		List<LogicProductionGetItemDO> getitemlist=logicProductionGetItemDAO.findListByExample(getitem);
		boolean bl =true;//是否全部使用完成
		for(int n=0;n<getitemlist.size();n++){
			BigDecimal bd = getitemlist.get(n).getZd007Quantity();
			for(int i=0;i<list.size();i++){
				if(getitemlist.get(n).getZd002MaterialsCode().equals(list.get(i).getZd002MaterialsCode())){
					bd=MathUtil.mathUtil.subtract(bd, list.get(i).getZd007Quantity());	
				}
			}
			if(bd.compareTo(new BigDecimal(0))==1){
				bl=false;
			}
		}
		return bl;
	}
}
